package tool

trait Reporter {
   // Informs scalac that this will be mixed-in with the class Compiler, so
   // we'll have access to the source file information (scala.io.Source has nice
   // methods for displaying error messages).
this: Compiler =>

	 private var foundErrors = false

	 /** Simple warnings */
	 def warn(msg: String): Unit = outputErrorMsg("Warning", msg)
				def warn(msg: String, i: Int): Unit = report(i, "Warning: " + msg)
							       def warn(msg: String, pos: Positional): Unit = warn(msg, pos.pos)

												       /** Non-fatal errors. The compiler should call terminateIfErrors
													* before the errors can have an impact (for instance at the end
													* of the phase). */
      def error(msg: String): Unit = { foundErrors = true; outputErrorMsg("Error", msg) }
      def error(msg: String, i: Int): Unit = { foundErrors = true; report(i, "Error: " + msg) }
      def error(msg: String, pos: Positional): Unit = error(msg, pos.pos)

					       /** Errors from which the compiler cannot recover or continue. */
	def fatalError(msg: String): Nothing = { outputErrorMsg("Fatal error", msg); terminate }
	def fatalError(msg: String, i: Int): Nothing = {
		report(i, "Fatal error: " + msg)
		terminate
	}

	def fatalError(msg: String, pos: Positional): Nothing = fatalError(msg, pos.pos)

						    /** Stops the compiler if they were non-fatal errors. */
	def terminateIfErrors = {
		if(foundErrors) {
			Console.err.println("There were errors.")
				terminate
		}
	}

      private def outputErrorMsg(prefix: String, msg: String) = {
	 Console.err.println(prefix + ": " + msg)
      }

      private def terminate: Nothing = {
	 exit(-1)
      }

      // circumvents what I think is a bug in scala.io.Source
      private def report(pos: Int, msg: String): Unit = {
	 val buf = new StringBuilder
	    val line = scala.io.Position.line(pos)
	    val col = scala.io.Position.column(pos)
	    buf.append(line + ":" + col + ": " + msg)
	    buf.append("\n")
	    buf.append(source.getLine(line))
	    buf.append("\n")
	    var i = 1
	    while(i < col) {
	       buf.append(' ')
		  i += 1
	    }
	 buf.append('^')
	    Console.err.println(buf.toString)
      }
}
